﻿using RabbitMQ.Client;

namespace RabbitMQ.Library
{
    /// <summary>
    /// RabbitMqClient上下文。
    /// 发送/接收/辅助功能的Connection/Channel分离，避免偶发性的消息串掉的错误。
    /// </summary>
    public class RabbitContext
    {
        /// <summary>
        /// 创建一个IConnection
        /// </summary>
        /// <returns></returns>
        public static IConnection CreateConnection()
        {
            var configDom = ConfigManager.config; //获取MQ的连接配置

            const ushort heartbeat = 60;
            var factory = new ConnectionFactory()
            {
                HostName = configDom.Host,
                UserName = configDom.UserName,
                Password = configDom.Password,
                VirtualHost = configDom.VirtualHost,
                Port = configDom.Port,
                RequestedHeartbeat = heartbeat, //心跳超时时间
                AutomaticRecoveryEnabled = true //自动重连
            };

            return factory.CreateConnection(); //创建连接对象
        }

        /// <summary>
        /// 创建一个IModel
        /// </summary>
        /// <param name="connection">IConnection.</param>
        /// <returns></returns>
        public static IModel CreateModel(IConnection connection)
        {
            return connection.CreateModel(); //创建通道
        }

        #region 发送消息的

        /// <summary>
        /// 用于发送消息的Connection。
        /// </summary>
        public IConnection SendConnection { get; internal set; }

        /// <summary>
        /// 用于发送消息的Channel。
        /// </summary>
        public IModel SendChannel { get; internal set; }

        #endregion

        #region 用户侦听的

        /// <summary>
        /// 用户侦听的Connection。
        /// </summary>
        public IConnection ListenConnection { get; internal set; }

        /// <summary>
        /// 用户侦听的Channel。
        /// </summary>
        public IModel ListenChannel { get; internal set; }

        /// <summary>
        /// 默认侦听的队列名称。
        /// </summary>
        public string ListenQueueName { get; internal set; }

        #endregion

        #region 辅助操作的
        /// <summary>
        /// 辅助操作的Connection。
        /// </summary>
        public IConnection AssistConnection { get; internal set; }

        /// <summary>
        /// 辅助操作的Channel。
        /// </summary>
        public IModel AssistChannel { get; internal set; }

        #endregion

        /// <summary>
        /// 实例编号。
        /// </summary>
        public string InstanceCode { get; set; }

    }
}
